package {{.pkg}}
{{if .withCache}}
import (
	"context"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/sqlc"
	"github.com/Masterminds/squirrel"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)
{{else}}
import (
	"context"
	"fmt"
	"github.com/Masterminds/squirrel"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"github.com/zeromicro/go-zero/core/stores/sqlc"
)
{{end}}
var _ {{.upperStartCamelObject}}Model = (*custom{{.upperStartCamelObject}}Model)(nil)

type (
	// {{.upperStartCamelObject}}Model is an interface to be customized, add more methods here,
	// and implement the added methods in custom{{.upperStartCamelObject}}Model.
	{{.upperStartCamelObject}}Model interface {
		{{.lowerStartCamelObject}}Model
		RowBuilder() squirrel.SelectBuilder
		Truncate(ctx context.Context)
		FindAll(ctx context.Context) ([]*{{.upperStartCamelObject}}, error)
		Count() (int64, error)
		Page(Current int64, PageSize int64) (*[]{{.upperStartCamelObject}}, error)
		PageByCondition(map[string]interface{}, int64, int64) (*[]{{.upperStartCamelObject}}, error)
	}

	custom{{.upperStartCamelObject}}Model struct {
		*default{{.upperStartCamelObject}}Model
	}
)

// New{{.upperStartCamelObject}}Model returns a model for the database table.
func New{{.upperStartCamelObject}}Model(conn sqlx.SqlConn{{if .withCache}}, c cache.CacheConf{{end}}) {{.upperStartCamelObject}}Model {
	return &custom{{.upperStartCamelObject}}Model{
		default{{.upperStartCamelObject}}Model: new{{.upperStartCamelObject}}Model(conn{{if .withCache}}, c{{end}}),
	}
}


func (m *default{{.upperStartCamelObject}}Model) RowBuilder() squirrel.SelectBuilder {
	return squirrel.Select({{.lowerStartCamelObject}}Rows).From(m.table)
}


func (m *default{{.upperStartCamelObject}}Model) Truncate(ctx context.Context) {
	build := m.RowBuilder()
	query, values, err := build.ToSql()
	if err == nil {
		var resp []*{{.upperStartCamelObject}}
		{{if .withCache}}
		err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
		{{else}}
		err = m.conn.QueryRowsCtx(ctx, &resp, query, values...)
		{{end}}
		if err == nil {
			for _, r := range resp {
				m.Delete(ctx, r.ID)
			}
			{{if .withCache}}
			m.ExecNoCacheCtx(ctx, fmt.Sprintf("TRUNCATE %s", m.tableName()))
			{{else}}
			m.conn.ExecCtx(ctx, fmt.Sprintf("TRUNCATE %s", m.tableName()))
			{{end}}
		}
	}
}



func (m *default{{.upperStartCamelObject}}Model) FindAll(ctx context.Context)  ([]*{{.upperStartCamelObject}}, error) {
	build := m.RowBuilder()
	query, values, err := build.ToSql()
	if err != nil {
		return nil, nil
	}

	var resp []*{{.upperStartCamelObject}}
	{{if .withCache}}
	err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
	{{else}}
	err = m.conn.QueryRowsCtx(ctx, &resp, query, values...)
	{{end}}
	switch err {
	case nil:
		return resp, nil
	default:
		return nil, err
	}
}


func (m *default{{.upperStartCamelObject}}Model) Count() (int64, error) {
	query := fmt.Sprintf("select count(*) as count from %s", m.table)

	var count int64
	{{if .withCache}}
	err := m.QueryRowNoCache(&count, query)
	{{else}}
	err := m.conn.QueryRow(&count, query)
	{{end}}

	switch err {
	case nil:
		return count, nil
	case sqlc.ErrNotFound:
		return 0, ErrNotFound
	default:
		return 0, err
	}
}

func (m *default{{.upperStartCamelObject}}Model) Page(Current int64, PageSize int64) (*[]{{.upperStartCamelObject}}, error) {

	query := fmt.Sprintf("select * from %s  limit ?,?", m.table)
	var resp []{{.upperStartCamelObject}}
	{{if .withCache}}
	err := m.QueryRowsNoCache(&resp, query, (Current-1)*PageSize, PageSize)
	{{else}}
	err := m.conn.QueryRows(&resp, query, (Current-1)*PageSize, PageSize)
	{{end}}
	switch err {
	case nil:
		return &resp, nil
	case sqlc.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	}
}

func (m *default{{.upperStartCamelObject}}Model) PageByCondition(conditions map[string]interface{}, Current int64, PageSize int64) (*[]{{.upperStartCamelObject}}, error) {
	query := m.RowBuilder().Limit(uint64(PageSize)).Offset(uint64((Current - 1) * PageSize))
	// 处理条件
	for key, value := range conditions {
		query = query.Where(fmt.Sprintf("%s = ?", key), value)
	}
	// 转换query为SQL语句
	sql, args, err := query.ToSql()
	if err != nil {
		// 处理error
		return nil, err
	}
	var resp []{{.upperStartCamelObject}}
	{{if .withCache}}
	err = m.QueryRowsNoCache(&resp, sql, args...)
	{{else}}
	err = m.QueryRows(&resp, sql, args...)
	{{end}}
	switch err {
	case nil:
		return &resp, nil
	case sqlc.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	}
}
